﻿interface IPararm {
  report?: string
  data?: string
  report_method?: string
  data_method?: string
  fun?: string
  printer?: string
  dataUrlParams?: Document | XMLHttpRequestBodyInit | null
  // 类型
  type?: string
  url?: string
  ver?: string
  // 是否显示打印选项对话框
  showOptionDlg?: boolean
  printerName?: string
  PaperName?: string
}

const OPEN = 1
const WSURL = 'ws://127.0.0.1:22333'

export const grwebappWs: {
  gridWebappWebsocket: WebSocket | null
  webappWsCreate: (open: () => void) => void
  webappWsCheck: (silence: boolean) => boolean
  webAppProtocolHref: (args?: { type: string; url: string; ver: string } | number | null) => string
  startGrid: () => void
  send: (data: string) => void
  request: (
    data: IPararm,
    report?: string,
    tableData?: string,
    callback?: (event: MessageEvent<string>) => void,
  ) => void
  envVerify: (appUpdate: boolean) => void
} = {
  gridWebappWebsocket: null,

  /**
   * 检查 ws 是否进行了连接
   * @param {*} silence 是否静默
   * @returns
   * @memberof PrintData
   */
  webappWsCheck(silence: boolean = false): boolean {
    if (!silence) {
      if (!this.gridWebappWebsocket) {
        console.log(`output->`, 'WebSocket没有创建，无法发送数据！')
        // 判断socket状态是否处于打开状态
      } else if (this.gridWebappWebsocket.readyState !== OPEN) {
        console.log(`output->`, 'WebSocket正在连接中，暂不能发送数据！')
      }
    }

    // socket已经初始化,并且socket状态正常 返回true
    return (this.gridWebappWebsocket ?? false) && this.gridWebappWebsocket?.readyState === OPEN
  },

  // 创建socket连接
  webappWsCreate(open) {
    // 判断当前浏览器是否支持WebSocket
    if (!('WebSocket' in window)) {
      console.log(`output->`, '当前浏览器不支持HTML5的WebSocket，请选用更新版本的浏览器！')
    }

    // 如果已经创建过了那么不需要重复创建
    if (this.gridWebappWebsocket && this.gridWebappWebsocket.readyState === OPEN) {
      return false
    }

    // 初始化websocket地址
    this.gridWebappWebsocket = new WebSocket(WSURL)
    if (open) {
      // socket打开触发
      this.gridWebappWebsocket.onopen = () => {
        // socket出现错误关闭loading
        open()
      }

      this.gridWebappWebsocket.onerror = () => {
        // socket出现错误关闭loading
        console.error(
          '创建WebSocket失败，可能是“WEB报表客户端程序”在本机没有安装，或在报表网页加载时没有调用启动函数进行启动。',
        )

        try {
          this.startGrid()
        } catch (error) {
          console.log(`output->error`, error)
        }
      }
    }
  },

  // 推送数据
  send(data: string) {
    // 如果socket没有启动
    if (!this.webappWsCheck(true)) {
      this.webappWsCreate(() => {
        this.gridWebappWebsocket!.send(data)
      })
      return false
    }

    // 如果socket已经启动, 则直接发送数据
    this.gridWebappWebsocket!.send(data)
  },

  /**
   * 发送数据, 并获取数据
   *  使用 ts 类型封装 <string>data 方便使用
   * @param data 数据
   * @param report 报表
   * @param tableData 表格数据
   * @param callback 回调
   */
  request(
    data: IPararm,
    report: string = '',
    tableData: string = '',
    callback?: (event: MessageEvent<string>) => void,
  ) {
    let msg = JSON.stringify(data)

    // 写入 报表模板
    if (report) {
      msg += report

      // 写入 报表数据
      if (tableData) {
        msg += tableData
      }
    }

    // 发送数据
    this.send(msg)

    // 监听数据
    this.gridWebappWebsocket!.onmessage = callback ?? (() => {})
  },

  // 获取软件启动协议
  webAppProtocolHref(args = null) {
    return `grwebapp://${args ? JSON.stringify(args) : ''}`
  },

  // 启动瑞浪报表  自动检测更新
  startGrid() {
    // 需要一个配置去配置启动时, 将参数进行传递
    window.location.href = this.webAppProtocolHref()
  },

  // 通过URL协议启动WEB报表客户端程序
  // 参数 appUpdate 指定是否自动更新WEB报表客户端程序，根据_grwebapp_version与已经安装的程序版本进行比较，按需进行自动升级
  envVerify(appUpdate: boolean): void {
    const arg = appUpdate
      ? {
          type: 'update',
          url: 'http://www.rubylong.cn/download/gridreport6-webapp.exe',
          ver: '6.8.3.0',
        }
      : 0

    window.location.href = this.webAppProtocolHref(arg)
  },
}
